/*!
 * kind-of <https://github.com/jonschlinkert/kind-of>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

const toString = Object.prototype.toString;

export default function kindOf(val) {
  if (val === null) {
    return 'null';
  }

  if (val === undefined) {
    return 'undefined';
  }

  if (typeof val !== 'object') {
    return typeof val;
  }

  if (Array.isArray(val)) {
    return 'array';
  }

  if (val.nodeType === 1) {
    return 'element';
  }

  const type = toString.call(val);

  if (type === '[object Object]') {
    return 'object';
  }

  if (type === '[object Arguments]') {
    return 'arguments';
  }

  if (type === '[object Date]') {
    return 'date';
  }

  if (type === '[object RegExp]') {
    return 'regexp';
  }

  if (type === '[object Error]') {
    return 'error';
  }

  if (type === '[object Map]') {
    return 'map';
  }

  if (type === '[object WeakMap]') {
    return 'weakmap';
  }

  if (type === '[object Set]') {
    return 'set';
  }

  if (type === '[object WeakSet]') {
    return 'weakset';
  }

  if (type === '[object Promise]') {
    return 'promise';
  }

  if (typeof Buffer !== 'undefined' && Buffer.isBuffer(val)) {
    return 'buffer';
  }

  // detect views in an ArrayBuffer
  if (typeof ArrayBuffer !== 'undefined') {
    if (ArrayBuffer.isView) {
      if (ArrayBuffer.isView(val)) {
        return 'view';
      }
    }
  }

  return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
};
